home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994 November: Tool Chest / Dev.CD Nov 94.toast / Tool Chest / QuickDraw GX / QuickDraw GX Info / QuickDraw GX Interfaces / Interfaces & Libraries / graphics libraries / scaler library.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-04-30  |  12.1 KB  |  330 lines  |  [TEXT/MPS ]

  1. /*
  2. **  scaler library.c    -   Routines used to call gxFont scalers directly
  3. **
  4. **  Copyright 1992 Apple Computer, Inc.  All rights reserved.
  5. */
  6.  
  7. #include <Memory.h>         /* NewPtr(), DisposePtr() */
  8. #include <GestaltEqu.h>         /* For calling Gestalt() */
  9.  
  10. #include "Components.h"         /* Component Manager declarations */
  11. #include "scaler types.h"           /* Scaler API declarations and definitions */
  12. #include "scaler library.h"     /* The library's decls and defs. */
  13.  
  14. #define kComponentScalerType    'sclr'          /* Type-gxTag for gxFont scaler components */
  15. #ifndef __powerc
  16. #define PostScalerError(c,e) (((c)->PostErrorFunction != nil && (e) != scaler_no_problem)? (c)->PostErrorFunction((c),(e)),e: e)
  17. #else
  18. #define PostScalerError(c,e) (((c)->PostErrorFunction && (e) != scaler_no_problem) ? CallPostErrorFunctionProc((c)->PostErrorFunction,(c),(e)),(e):(e))
  19. #endif
  20.  
  21. typedef struct {
  22.     gxFontFormatTag       format;                 /* Font format the scaler supports */
  23.     Component       theScalerComponent;         /* Used to open the component scaler */
  24.     ComponentInstance   theOpenedScalerComponent;   /* Component scaler (if 0, needs opening)*/
  25. } scalerEntry, *scalerEntryPtr;                 /* Information associated with a component gxFont scaler */
  26.  
  27. typedef struct {
  28.     long                oldSeed;                    /* Component Mgr's instance seed */
  29.     long                numScalers;             /* Number of scalers in the list */
  30.     scalerEntry     entries[1];             /* The array of scalers */
  31. } scalerList, *scalerListPtr;                       /* Component gxFont scaler list structure */
  32.  
  33. static  scalerListPtr   theListOfScalers = nil;     /* The list (really an array) of all registered component scalers */
  34.  
  35. static  Boolean     FindComponentFontScalers(void);
  36. static  scalerError FindMatchingOpenScaler(ComponentInstance *theScaler, scalerContext *theContext);
  37. static  Boolean     FindComponentFontScalers(void);
  38. static  scalerListPtr   BuildScalerList(void);
  39. static  scalerEntryPtr  FindMatchingScaler(scalerListPtr theList, gxFontFormatTag format);
  40. static  scalerListPtr   UpdateScalerList(scalerListPtr oldList);
  41.  
  42. scalerError FontScalerOpen( scalerContext* context, scalerInfo* theInfo)
  43. {
  44.     scalerError error;
  45.     ComponentInstance   theOpenScaler;
  46.     
  47.     if (!context) return scaler_null_context;
  48.     
  49.     if (theListOfScalers == nil)
  50.         if (!FindComponentFontScalers())
  51.             return PostScalerError(context,scaler_unsupported_font_format);
  52.     
  53.     if ((error = FindMatchingOpenScaler(&theOpenScaler, context)) == 0) {
  54.         error = ComponentFontScalerOpen(theOpenScaler, context, theInfo);
  55.     }
  56.     
  57.     return error;
  58. }
  59.  
  60. scalerError FontScalerClose( scalerContext* context)
  61. {
  62.     scalerError error;
  63.     ComponentInstance   theOpenScaler;
  64.     
  65.     if (!context) return scaler_null_context;
  66.  
  67.     if ((error = FindMatchingOpenScaler(&theOpenScaler, context)) == 0) {
  68.         error = ComponentFontScalerClose(theOpenScaler, context);
  69.     }
  70.     
  71.     return error;
  72. }
  73.  
  74. scalerError FontScalerNewFont( scalerContext* context, scalerFontInfo* info)
  75. {
  76.     scalerError error;
  77.     ComponentInstance   theOpenScaler;
  78.     
  79.     if (!context) return scaler_null_context;
  80.  
  81.     if ((error = FindMatchingOpenScaler(&theOpenScaler, context)) == 0) {
  82.         error = ComponentFontScalerNewFont(theOpenScaler, context, info);
  83.     }
  84.     
  85.     return error;
  86. }
  87.  
  88. scalerError FontScalerNewVariation( scalerContext* context, long count, const gxFontVariation variation[])
  89. {
  90.     scalerError error;
  91.     ComponentInstance   theOpenScaler;
  92.     
  93.     if (!context) return scaler_null_context;
  94.  
  95.     if ((error = FindMatchingOpenScaler(&theOpenScaler, context)) == 0) {
  96.         error = ComponentFontScalerNewVariation(theOpenScaler, context, count, (gxFontVariation*)variation);
  97.     }
  98.     
  99.     return error;
  100. }
  101.  
  102. scalerError FontScalerNewTransform( scalerContext* context, const scalerTransform* trans, scalerTransformInfo* info)
  103. {
  104.     scalerError error;
  105.     ComponentInstance   theOpenScaler;
  106.     
  107.     if (!context) return scaler_null_context;
  108.  
  109.     if ((error = FindMatchingOpenScaler(&theOpenScaler, context)) == 0) {
  110.         error = ComponentFontScalerNewTransform(theOpenScaler, context, trans, info);
  111.     }
  112.     
  113.     return error;
  114. }
  115.  
  116. scalerError FontScalerNewGlyph( scalerContext* context, const scalerGlyph* glyph, scalerMetrics* theMetrics, scalerBitmap* bitImage, void* outlineData)
  117. {
  118.     scalerError error;
  119.     ComponentInstance   theOpenScaler;
  120.     
  121.     if (!context) return scaler_null_context;
  122.  
  123.     if ((error = FindMatchingOpenScaler(&theOpenScaler, context)) == 0) {
  124.         error = ComponentFontScalerNewGlyph(theOpenScaler, context, glyph, theMetrics, bitImage, outlineData);
  125.     }
  126.     
  127.     return error;
  128. }
  129.  
  130. scalerError FontScalerKernGlyphs( scalerContext* context, scalerKerning* kerning, gxPoint deltas[], scalerKerningNote flags[], gxPoint locations[])
  131. {
  132.     scalerError error;
  133.     ComponentInstance   theOpenScaler;
  134.     
  135.     if (!context) return scaler_null_context;
  136.  
  137.     if ((error = FindMatchingOpenScaler(&theOpenScaler, context)) == 0) {
  138.         error = ComponentScalerKernGlyphs(theOpenScaler, context,  kerning, deltas, flags, locations);
  139.     }
  140.     
  141.     return error;
  142. }
  143.  
  144. scalerError FontScalerStreamFont( scalerContext* context, scalerStream* stream)
  145. {
  146.     scalerError error;
  147.     ComponentInstance   theOpenScaler;
  148.     
  149.     if (!context) return scaler_null_context;
  150.  
  151.     if ((error = FindMatchingOpenScaler(&theOpenScaler, context)) == 0) {
  152.         error = ComponentFontScalerStreamFont(theOpenScaler, context, stream);
  153.     }
  154.     
  155.     return error;
  156. }
  157.  
  158. /*
  159. **  CloseAllOpenFontScalers()   -   Runs down the list of registered component scalers and closes the open ones.
  160. */
  161. void    CloseAllOpenFontScalers(void)
  162. {
  163.     if (theListOfScalers != nil) {
  164.         unsigned short  whichScaler;
  165.         
  166.         for (whichScaler = 0; whichScaler < theListOfScalers->numScalers; whichScaler++) {
  167.             if (theListOfScalers->entries[whichScaler].theOpenedScalerComponent != nil) {
  168.                 CloseComponent(theListOfScalers->entries[whichScaler].theOpenedScalerComponent);
  169.             }
  170.         }
  171.         
  172.         DisposePtr((Ptr)theListOfScalers);
  173.         theListOfScalers = nil;
  174.     }
  175. }
  176.  
  177. /*
  178. **  FindComponentFontScalers()  -   Called during the first ScalerOpen() call, this routine first determines whether the 
  179. **                          Component Manager is present.  If it is, it registers the built-in scalers and then
  180. **                          asks the Component Manager to find all of the registered scaler components.  A list
  181. **                          of these is built, and if all goes well the routine will return true, indicating that
  182. **                          component gxFont scalers are in use.  If it returns false, the built-in scalers will
  183. **                          need to be called directly.
  184. */
  185. static  Boolean FindComponentFontScalers()
  186. {
  187.     long    dummyLong;
  188.     
  189.     if (Gestalt(gestaltComponentMgr, &dummyLong) == 0) {
  190.         if ((theListOfScalers = BuildScalerList()) != 0) {
  191.             return true;
  192.         }
  193.     }
  194.  
  195.     return false;
  196. }
  197.  
  198. /*
  199. **  FindMatchingScaler()    -   Given a gxFont format and the list of all registered component gxFont scalers, it looks for
  200. **                      a scaler (actually the first) that supports the format and returns the address of
  201. **                      its list entry.  It will return nil if no scaler is found for the format.
  202. */
  203. static  scalerEntryPtr  FindMatchingScaler(register scalerListPtr theList, gxFontFormatTag format)
  204. {
  205.     unsigned short  numScalers;
  206.     register scalerEntryPtr entry;
  207.     
  208.     numScalers = theList->numScalers;
  209.     entry = theList->entries;
  210.     do {
  211.         if (entry->format == format)
  212.             return entry;
  213.         entry++;
  214.     } while (--numScalers);
  215.     
  216.     return nil;
  217. }
  218.  
  219. /*
  220. **  UpdateScalerList()  -   Builds a new list of registered scalers in response to a changed component list
  221. **                      seed.  It copies from the old list the entries for those scalers that are in both lists.
  222. */
  223. static  scalerListPtr   UpdateScalerList(scalerListPtr oldList)
  224. {
  225.     scalerListPtr       newList;
  226.     unsigned short      whichScaler;
  227.     scalerEntryPtr      oldEntry;
  228.     
  229.     newList = BuildScalerList();        /* Create an all-new scaler list */
  230.     
  231.     /* We copy the entries from the old list for those scalers in both lists (they may be open)*/
  232.     for (whichScaler = 0; whichScaler < newList->numScalers; whichScaler++) {
  233.         if ((oldEntry = FindMatchingScaler(oldList, newList->entries[whichScaler].format)) != 0) {
  234.             newList->entries[whichScaler] = *oldEntry;
  235.         }
  236.     }
  237.     
  238.     DisposePtr((Ptr)oldList);
  239.     theListOfScalers = newList;
  240.     
  241.     return newList;
  242. }
  243.  
  244. /*
  245. **  BuildScalerList()   -   Queries the Component Manager to find all currently registered component scalers.
  246. **                      It allocates and builds a list of these scalers.
  247. */
  248. static  scalerListPtr   BuildScalerList()
  249. {
  250.     long                    numScalers;
  251.     ComponentDescription    looking, theInfo;
  252.     register    scalerListPtr   newList = nil;
  253.     
  254.     /* Fill in the description structure */
  255.     looking.componentType           = kComponentScalerType;
  256.     looking.componentSubType            = kAnyComponentSubType;
  257.     looking.componentManufacturer       = kAnyComponentManufacturer;
  258.     looking.componentFlags          = 0;
  259.     looking.componentFlagsMask      = 0;
  260.     
  261.     /* Count the number of components and create our list based on that number*/
  262.     
  263.     numScalers = CountComponents(&looking);
  264.     
  265.     {   register scalerEntryPtr entry;
  266.         Component           lastComponent = 0, currentComponent;
  267.         
  268.         newList = (scalerListPtr) NewPtr(sizeof(scalerList) + (numScalers - 1)*sizeof(scalerEntry));
  269.         
  270.         newList->oldSeed        = GetComponentListModSeed();
  271.         newList->numScalers = numScalers;
  272.             
  273.         /* For each scaler, get its info and remember the subtype, this is the format */
  274.         entry = newList->entries;
  275.         do {
  276.             currentComponent = FindNextComponent(lastComponent, &looking);
  277.         
  278.             if (GetComponentInfo(currentComponent,&theInfo, nil, nil, nil) == 0) {
  279.                 entry->format                   = theInfo.componentSubType;
  280.                 entry->theScalerComponent       = currentComponent;
  281.                 entry->theOpenedScalerComponent = nil;
  282.             } else
  283.                 entry->format = 0;  /* unusable scaler */
  284.                 
  285.             lastComponent = currentComponent;
  286.             entry++;
  287.         } while(--numScalers);
  288.     }
  289.     
  290.     return newList;
  291. }
  292.  
  293. /*
  294. **  FindMatchingOpenScaler()    -   This routine will look for a component scaler that supports the gxFont format
  295. **                          specified in the given scalerContext.  If necessary, the list of scalers will be
  296. **                          updated.  If a matching component scaler is found and is not open, the component
  297. **                          is opened.
  298. **
  299. **                          The routine returns scaler_no_problem if all went well,
  300. **                          scaler_unsupported_font_format if a component was not found or couldn't be
  301. **                          opened.
  302. **
  303. **                          If scaler_no_problem is returned *theOpenScaler will contain the
  304. **                          component instance for the desired scaler, else it will be undefined.
  305. */
  306. static  scalerError FindMatchingOpenScaler(ComponentInstance* theOpenScaler, scalerContext* theContext)
  307. {
  308.     scalerError result = scaler_no_problem;
  309.     scalerEntryPtr  theScaler;
  310.     
  311.     /* Check if a component was added while we were away, we may need to update the list of scalers */
  312.     if (GetComponentListModSeed() != theListOfScalers->oldSeed)
  313.         theListOfScalers = UpdateScalerList(theListOfScalers);
  314.         
  315.     theScaler = FindMatchingScaler(theListOfScalers, theContext->format);
  316.     
  317.     if (theScaler == nil) { 
  318.         result = scaler_unsupported_font_format;
  319.     } else {
  320.         if (theScaler->theOpenedScalerComponent == nil) {
  321.             if ((theScaler->theOpenedScalerComponent = OpenComponent(theScaler->theScalerComponent)) == nil)
  322.                 result = scaler_unsupported_font_format;
  323.         }
  324.         
  325.         *theOpenScaler = theScaler->theOpenedScalerComponent;
  326.     }
  327.     
  328.     return PostScalerError(theContext, result);
  329. }
  330.